package com.changxianggu.cloud.edu.tool.core;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.changxianggu.cloud.edu.tool.entity.error.*;
import com.changxianggu.cloud.edu.tool.entity.gen.GenCodeEntity;
import com.changxianggu.cloud.edu.tool.entity.vo.*;
import com.changxianggu.cloud.edu.tool.key.StudentKeyProperty;
import com.changxianggu.cloud.edu.tool.key.TeacherKeyProperty;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liuyuantao
 */
@Data
public class ExtraDataUtil {

    List<String> errorList = new ArrayList<>();

    /**
     * 从excel里面抽取院系数据
     *
     * @param collegeMap
     * @param dataList
     * @param nameKey
     * @param codeKey
     * @return
     */
    public Map<String, Object> extractCollegeData(Map<String, Object> collegeMap, List<Map<String, Object>> dataList,
                                                  String nameKey, String codeKey, boolean genCollege, String excelName) {


        //未设置key的话不能进行提取
        if (CollUtil.isEmpty(dataList)) {
            return collegeMap;
        }
        int currentCount = 1;
        String parentCode = "";
        for (Map<String, Object> dataObj : dataList) {
            //从excel的数据里抽取名字和代码
            String extraName = ExtraNameCodeUtil.extraObjName(dataObj, nameKey);
            String extraCode = ExtraNameCodeUtil.extraObjName(dataObj, codeKey);
            if (StrUtil.isBlank(extraName) && StrUtil.isBlank(extraCode)) {
                continue;
            }
            if (StrUtil.isBlank(extraCode)) {
                //代码不存在,extraName肯定不是空,可能会存在生成代码的可能
                boolean existCode = false;
                //通过名字循环查找院系代码
                for (Object collegeObj : collegeMap.values()) {
                    CollegeVO college = (CollegeVO) collegeObj;
                    String name = college.getName();
                    if (StrUtil.equalsIgnoreCase(name, extraName)) {
                        extraCode = college.getCode();
                        existCode = true;
                        break;
                    }
                }
                if (!existCode) {
                    //使用名字也没找到院系代码
                    if (genCollege) {
                        //设置了自动生成代码
                        GenCodeEntity genCodeEntity = ExtraNameCodeUtil.genCode4Data(parentCode, currentCount, collegeMap);
                        currentCount = genCodeEntity.getCurrentCount() + 1;
                        extraCode = genCodeEntity.getCode();
                        CollegeVO collegeVO = new CollegeVO();
                        collegeVO.setCode(extraCode);
                        collegeVO.setName(extraName);
                        //生成完后将组装好的院系数据存在临时缓存
                        collegeMap.put(extraCode, collegeVO);
                    } else {
                        //未设置自动生成代码,直接报错处理
                        errorList.add(StrUtil.format(CollegeError.NO_CODE, excelName, extraName));
                    }
                }
            } else {
                //代码不为空
                Object collegeObj = collegeMap.get(extraCode);
                if (collegeObj == null) {
                    //指定的院系代码没有在临时缓存中
                    if (StrUtil.isBlank(extraName)) {
                        errorList.add(StrUtil.format(CollegeError.NO_NAME, excelName, extraCode));
                    } else {
                        CollegeVO collegeVO = new CollegeVO();
                        collegeVO.setCode(extraCode);
                        collegeVO.setName(extraName);
                        //生成完后将组装好的院系数据存在临时缓存
                        collegeMap.put(extraCode, collegeVO);
                    }
                } else {
                    //通过代码在临时缓存找到院系
                    CollegeVO collegeVO = (CollegeVO) collegeObj;
                    String collegeVOName = collegeVO.getName();
                    if (StrUtil.isNotBlank(extraName)) {
                        //比对填写的院系名和缓存里面的院系名是否一样
                        if (!StrUtil.equalsIgnoreCase(extraName, collegeVOName)) {
                            errorList.add(StrUtil.format(CollegeError.MULTI_NAME, excelName, extraCode));
                        }
                    }
                }
            }
        }
        return collegeMap;
    }


    /**
     * 从excel里面抽取数据
     *
     * @param majorMap
     * @param dataList
     * @param nameKey
     * @param codeKey
     * @return
     */
    public Map<String, Object> extractMajorData(Map<String, Object> collegeMap,
                                                Map<String, Object> majorMap,
                                                List<Map<String, Object>> dataList,
                                                String nameKey,
                                                String codeKey,
                                                String collegeNameKey,
                                                String collegeCodeKey, String typeNameKey, boolean genMajor, String excelName) {
        //未设置key的话不能进行提取
        if (CollUtil.isEmpty(dataList)) {
            return majorMap;
        }
        //记录学院代码生成专业代码的最大值
        Map<String, Integer> recordCurrentMap = new HashMap<>(32);
        for (Map<String, Object> dataObj : dataList) {
            //自动生成代码的索引
            int currentCount = 1;
            String extraMajorName = ExtraNameCodeUtil.extraObjName(dataObj, nameKey);
            String extraMajorCode = ExtraNameCodeUtil.extraObjName(dataObj, codeKey);
            if (StrUtil.isBlank(extraMajorName) && StrUtil.isBlank(extraMajorCode)) {
                //如果没有填写名称和代码,直接跳转不需要抽取
                continue;
            }
            //准备提取学院处理学院的异常
            String collegeName = null;
            String collegeCode = null;
            CollegeVO extraCollege = extraCollegeNameCode(collegeMap, dataObj, collegeNameKey, collegeCodeKey);
            String collegeErrorMessage = extraCollege.getErrorMessage();
            if (collegeErrorMessage == null) {
                //说明提取到了院系的数据
                collegeName = extraCollege.getName();
                collegeCode = extraCollege.getCode();
            } else {
                if (StrUtil.equals("1", collegeErrorMessage)) {
                    //没有填写院系名和院系代码
                    String errorName = extraMajorName == null ? extraMajorCode : extraMajorName;
                    errorList.add(StrUtil.format(MajorError.NO_COLLEGE_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(collegeErrorMessage, excelName, "专业"));
                }
            }
            /////////////////抽取专业///////////////////////////////////////////
            if (StrUtil.isBlank(extraMajorCode)) {
                //代码不存在,extraName肯定不是空,可能会存在生成代码的可能
                boolean existCode = false;
                //通过名字循环查找院系代码
                for (Object majorObj : majorMap.values()) {
                    MajorVO major = (MajorVO) majorObj;
                    String name = major.getName();
                    if (StrUtil.equalsIgnoreCase(name, extraMajorName)) {
                        extraMajorCode = major.getCode();
                        existCode = true;
                        break;
                    }
                }
                if (!existCode) {
                    //使用名字也没找到专业代码
                    if (genMajor) {
                        currentCount = recordCurrentMap.get(collegeCode) == null ? 1 : recordCurrentMap.get(collegeCode);
                        //设置了自动生成代码
                        GenCodeEntity genCodeEntity = ExtraNameCodeUtil.genCode4Data(collegeCode, currentCount, majorMap);
                        currentCount = genCodeEntity.getCurrentCount() + 1;
                        //记录当前学院自动生成代码的最大值
                        recordCurrentMap.put(collegeCode, currentCount);
                        extraMajorCode = genCodeEntity.getCode();
                        MajorVO majorVO = new MajorVO();
                        majorVO.setCode(extraMajorCode);
                        majorVO.setName(extraMajorName);
                        majorVO.setCollegeCode(collegeCode);
                        majorVO.setCollegeName(collegeName);
                        if (StrUtil.isNotBlank(typeNameKey)) {
                            Object typeNameObj = dataObj.get(typeNameKey);
                            if (typeNameObj != null) {
                                majorVO.setType(typeNameObj.toString().trim());
                            }
                        }
                        //生成完后将组装好的专业数据存在临时缓存
                        majorMap.put(extraMajorCode, majorVO);
                    } else {
                        //未设置自动生成代码,直接报错处理
                        errorList.add(StrUtil.format(MajorError.NO_CODE, excelName, extraMajorName));
                    }
                }
            } else {
                //代码不为空
                Object majorObj = majorMap.get(extraMajorCode);
                if (majorObj == null) {
                    //指定的专业代码没有在临时缓存中
                    if (StrUtil.isBlank(extraMajorName)) {
                        errorList.add(StrUtil.format(MajorError.NO_NAME, excelName, extraMajorCode));
                    } else {
                        MajorVO majorVO = new MajorVO();
                        majorVO.setCode(extraMajorCode);
                        majorVO.setName(extraMajorName);
                        majorVO.setCollegeName(collegeName);
                        majorVO.setCollegeCode(collegeCode);
                        if (StrUtil.isNotBlank(typeNameKey)) {
                            Object typeNameObj = dataObj.get(typeNameKey);
                            if (typeNameObj != null) {
                                majorVO.setType(typeNameObj.toString().trim());
                            }
                        }
                        //生成完后将组装好的专业数据存在临时缓存
                        majorMap.put(extraMajorCode, majorVO);
                    }
                } else {
                    //通过代码在临时缓存找到专业
                    MajorVO majorVO = (MajorVO) majorObj;
                    String majorVOName = majorVO.getName();
                    if (StrUtil.isNotBlank(extraMajorName)) {
                        //比对填写的专业名和缓存里面的专业名是否一样
                        if (!StrUtil.equalsIgnoreCase(extraMajorName, majorVOName)) {
                            errorList.add(StrUtil.format(MajorError.MULTI_NAME, excelName, extraMajorCode));
                        }
                    }
                    //校验相同专业,院系代码不一样
                    String cacheMajorCollegeCode = majorVO.getCollegeCode();
                    if (!StrUtil.equalsIgnoreCase(cacheMajorCollegeCode, collegeCode)) {
                        errorList.add(StrUtil.format(MajorError.MULTI_COLLEGE, excelName, extraMajorCode));
                    }
                }
            }
        }
        return majorMap;
    }

    /**
     * 从excel里面抽取数据
     *
     * @param majorMap
     * @param dataList
     * @param nameKey
     * @param codeKey
     * @return
     */
    public Map<String, Object> extractMajorFxData(Map<String, Object> collegeMap, Map<String, Object> majorMap,
                                                  List<Map<String, Object>> dataList,
                                                  String nameKey,
                                                  String codeKey,
                                                  String collegeNameKey,
                                                  String collegeCodeKey, String excelName) {
        //TODO 暂时从专业里面获取专业方向号
        return majorMap;
    }

    /**
     * 从excel里面抽取教研室数据
     *
     * @param collegeMap
     * @param officeMap
     * @param dataList
     * @param nameKey
     * @param codeKey
     * @return
     */
    public Map<String, Object> extractOfficeData(Map<String, Object> collegeMap,
                                                 Map<String, Object> officeMap,
                                                 List<Map<String, Object>> dataList,
                                                 String nameKey,
                                                 String codeKey,
                                                 String collegeNameKey,
                                                 String collegeCodeKey,
                                                 boolean genOffice,
                                                 String excelName) {
        //未设置key的话不能进行提取
        if (CollUtil.isEmpty(dataList)) {
            return officeMap;
        }
        //记录学院代码生成教研室代码的最大值
        Map<String, Integer> recordCurrentMap = new HashMap<>(32);
        for (Map<String, Object> dataObj : dataList) {
            //自动生成代码的索引
            int currentCount = 1;
            String extraOfficeName = ExtraNameCodeUtil.extraObjName(dataObj, nameKey);
            String extraOfficeCode = ExtraNameCodeUtil.extraObjName(dataObj, codeKey);
            if (StrUtil.isBlank(extraOfficeName) && StrUtil.isBlank(extraOfficeCode)) {
                //如果没有填写名称和代码,直接跳转不需要抽取
                continue;
            }
            //准备提取学院处理学院的异常
            String collegeName = null;
            String collegeCode = null;
            CollegeVO extraCollege = extraCollegeNameCode(collegeMap, dataObj, collegeNameKey, collegeCodeKey);
            String collegeErrorMessage = extraCollege.getErrorMessage();
            if (collegeErrorMessage == null) {
                //说明提取到了院系的数据
                collegeName = extraCollege.getName();
                collegeCode = extraCollege.getCode();
            } else {
                if (StrUtil.equals("1", collegeErrorMessage)) {
                    //没有填写院系名和院系代码
                    String errorName = extraOfficeName == null ? extraOfficeCode : extraOfficeName;
                    errorList.add(StrUtil.format(OfficeError.NO_COLLEGE_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(collegeErrorMessage, excelName, "教研室"));
                }
            }
            /////////////////抽取教研室///////////////////////////////////////////
            if (StrUtil.isBlank(extraOfficeCode)) {
                //代码不存在,extraName肯定不是空,可能会存在生成代码的可能
                boolean existCode = false;
                //通过名字循环查找院系代码
                for (Object officeObj : officeMap.values()) {
                    OfficeVO office = (OfficeVO) officeObj;
                    String name = office.getName();
                    if (StrUtil.equalsIgnoreCase(name, extraOfficeName)) {
                        extraOfficeCode = office.getCode();
                        existCode = true;
                        break;
                    }
                }
                if (!existCode) {
                    //使用名字也没找到院系代码
                    if (genOffice) {
                        currentCount = recordCurrentMap.get(collegeCode) == null ? 1 : recordCurrentMap.get(collegeCode);
                        //设置了自动生成代码
                        GenCodeEntity genCodeEntity = ExtraNameCodeUtil.genCode4Data(collegeCode, currentCount, officeMap);
                        currentCount = genCodeEntity.getCurrentCount() + 1;
                        //记录当前学院自动生成代码的最大值
                        recordCurrentMap.put(collegeCode, currentCount);
                        extraOfficeCode = genCodeEntity.getCode();
                        OfficeVO officeVO = new OfficeVO();
                        officeVO.setCode(extraOfficeCode);
                        officeVO.setName(extraOfficeName);
                        officeVO.setCollegeCode(collegeCode);
                        officeVO.setCollegeName(collegeName);
                        //生成完后将组装好的院系数据存在临时缓存
                        officeMap.put(extraOfficeCode, officeVO);
                    } else {
                        //未设置自动生成代码,直接报错处理
                        errorList.add(StrUtil.format(OfficeError.NO_CODE, excelName, extraOfficeName));
                    }
                }
            } else {
                //代码不为空
                Object officeObj = officeMap.get(extraOfficeCode);
                if (officeObj == null) {
                    //指定的教研室代码没有在临时缓存中
                    if (StrUtil.isBlank(extraOfficeName)) {
                        errorList.add(StrUtil.format(OfficeError.NO_NAME, excelName, extraOfficeCode));
                    } else {
                        OfficeVO officeVO = new OfficeVO();
                        officeVO.setCode(extraOfficeCode);
                        officeVO.setName(extraOfficeName);
                        officeVO.setCollegeName(collegeName);
                        officeVO.setCollegeCode(collegeCode);
                        //生成完后将组装好的院系数据存在临时缓存
                        officeMap.put(extraOfficeCode, officeVO);
                    }
                } else {
                    //通过代码在临时缓存找到教研室
                    OfficeVO officeVO = (OfficeVO) officeObj;
                    String officeVOName = officeVO.getName();
                    if (StrUtil.isNotBlank(extraOfficeName)) {
                        //比对填写的教研室名和缓存里面的教研室名是否一样
                        if (!StrUtil.equalsIgnoreCase(extraOfficeName, officeVOName)) {
                            errorList.add(StrUtil.format(OfficeError.MULTI_NAME, excelName, extraOfficeCode));
                        }
                    }
                    //相同教研室,院系不一样
                    String cacheCollegeCode = officeVO.getCollegeCode();
                    if (!StrUtil.equalsIgnoreCase(cacheCollegeCode, collegeCode)) {
                        errorList.add(StrUtil.format(OfficeError.MULTI_COLLEGE_CODE, excelName, extraOfficeName));
                    }
                }
            }
        }
        return officeMap;
    }

    /**
     * 从excel里面抽取教师数据
     *
     * @param collegeMap
     * @param teacherMap
     * @param dataList
     * @param teacherKeyProperty
     * @return
     */
    public Map<String, Object> extractTeacherData(Map<String, Object> collegeMap,
                                                  Map<String, Object> teacherMap,
                                                  List<Map<String, Object>> dataList,
                                                  TeacherKeyProperty teacherKeyProperty, String excelName) {
        String nameKey = teacherKeyProperty.getTeacherNameKey();
        String codeKey = teacherKeyProperty.getTeacherCodeKey();
        //未设置key的话不能进行提取
        if (CollUtil.isEmpty(dataList)) {
            return teacherMap;
        }
        String collegeNameKey = teacherKeyProperty.getTeacherCollegeNameKey();
        String collegeCodeKey = teacherKeyProperty.getTeacherCollegeCodeKey();
        String teacherJobTitleKey = teacherKeyProperty.getTeacherJobTitleKey();
        String teacherMobileKey = teacherKeyProperty.getTeacherMobileKey();
        String teacherSexNameKey = teacherKeyProperty.getTeacherSexNameKey();
        for (Map<String, Object> dataObj : dataList) {
            //教师的附属信息
            String teacherJobTitle = ExtraNameCodeUtil.extraObjName(dataObj, teacherJobTitleKey);
            String teacherMobile = ExtraNameCodeUtil.extraObjName(dataObj, teacherMobileKey);
            String teacherSexName = ExtraNameCodeUtil.extraObjName(dataObj, teacherSexNameKey);
            //从excel的数据里抽取名字和代码
            String extraTeacherName = ExtraNameCodeUtil.extraObjName(dataObj, nameKey);
            String extraTeacherCode = ExtraNameCodeUtil.extraObjName(dataObj, codeKey);
            if (StrUtil.isBlank(extraTeacherName) && StrUtil.isBlank(extraTeacherCode)) {
                //未填写教师名和教师工号,直接不进行抽取
                continue;
            }
            //准备提取学院处理学院的异常
            String collegeName = null;
            String collegeCode = null;
            CollegeVO extraCollege = extraCollegeNameCode(collegeMap, dataObj, collegeNameKey, collegeCodeKey);
            String collegeErrorMessage = extraCollege.getErrorMessage();
            if (collegeErrorMessage == null) {
                //说明提取到了院系的数据
                collegeName = extraCollege.getName();
                collegeCode = extraCollege.getCode();
            } else {
                if (StrUtil.equals("1", collegeErrorMessage)) {
                    //没有填写院系名和院系代码
                    String errorName = extraTeacherName == null ? extraTeacherCode : extraTeacherName;
                    errorList.add(StrUtil.format(TeacherError.NO_COLLEGE_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(collegeErrorMessage, excelName, "教师"));
                }
            }
            if (StrUtil.isBlank(extraTeacherCode)) {
                //代码不存在,extraName肯定不是空
                boolean existCode = false;
                //通过名字循环查找院系代码
                for (Object teacherObj : teacherMap.values()) {
                    TeacherVO teacher = (TeacherVO) teacherObj;
                    String name = teacher.getName();
                    if (StrUtil.equalsIgnoreCase(name, extraTeacherName)) {
                        existCode = true;
                        break;
                    }
                }
                if (!existCode) {
                    //没填写代码,通过教师名字也没找到
                    errorList.add(StrUtil.format(TeacherError.NO_CODE, excelName, extraTeacherName));
                }
            } else {
                //代码不为空
                Object teacherObj = teacherMap.get(extraTeacherCode);
                if (teacherObj == null) {
                    //指定的教师工号没有在临时缓存中
                    if (StrUtil.isBlank(extraTeacherName)) {
                        errorList.add(StrUtil.format(TeacherError.NO_NAME, excelName, extraTeacherCode));
                    } else {
                        TeacherVO teacherVO = new TeacherVO();
                        teacherVO.setCode(extraTeacherCode);
                        teacherVO.setName(extraTeacherName);
                        teacherVO.setCollegeName(collegeName);
                        teacherVO.setCollegeCode(collegeCode);
                        teacherVO.setJobTitle(teacherJobTitle);
                        teacherVO.setSex(teacherSexName);
                        teacherVO.setMobile(teacherMobile);
                        //生成完后将组装好的教师数据存在临时缓存
                        teacherMap.put(extraTeacherCode, teacherVO);
                    }
                } else {
                    //通过代码在临时缓存找到教师
                    TeacherVO teacherVO = (TeacherVO) teacherObj;
                    String teacherVOName = teacherVO.getName();
                    if (StrUtil.isNotBlank(extraTeacherName)) {
                        //比对填写的教师姓名和缓存里面的教师姓名是否一样
                        if (!StrUtil.equalsIgnoreCase(extraTeacherName, teacherVOName)) {
                            errorList.add(StrUtil.format(TeacherError.MULTI_NAME, excelName, extraTeacherCode));
                        }
                    }
                    //工号相同,所属的院系代码不同
                    String cacheCollegeCode = teacherVO.getCollegeCode();
                    if (!StrUtil.equalsIgnoreCase(cacheCollegeCode, collegeCode)) {
                        errorList.add(StrUtil.format(TeacherError.MULTI_COLLEGE_CODE, excelName, teacherVOName));
                    }
                }
            }
        }
        return teacherMap;
    }

    /**
     * @param clazzMap
     * @param collegeMap
     * @param majorMap
     * @param dataList
     * @param nameKey
     * @param codeKey
     * @param majorNameKey
     * @param majorCodeKey
     * @param collegeNameKey
     * @param collegeCodeKey
     * @param clazzNumKey
     * @param clazzCampusKey
     * @param clazzGradeKey
     * @param excelName
     * @return
     */
    public Map<String, Object> extractClazzData(Map<String, Object> clazzMap,
                                                Map<String, Object> collegeMap,
                                                Map<String, Object> majorMap,
                                                List<Map<String, Object>> dataList,
                                                String nameKey,
                                                String codeKey,
                                                String majorNameKey,
                                                String majorCodeKey,
                                                String collegeNameKey,
                                                String collegeCodeKey,
                                                String clazzNumKey,
                                                String clazzCampusKey,
                                                String clazzGradeKey,
                                                boolean genClazz,
                                                String excelName) {
        //未设置key的话不能进行提取
        if (CollUtil.isEmpty(dataList)) {
            return clazzMap;
        }
        //记录专业代码生成班级代码的最大值
        Map<String, Integer> recordCurrentMap = new HashMap<>(32);
        for (Map<String, Object> dataObj : dataList) {
            //自动生成代码的索引
            String clazzNumber = ExtraNameCodeUtil.extraObjName(dataObj, clazzNumKey);
            String clazzCampus = ExtraNameCodeUtil.extraObjName(dataObj, clazzCampusKey);
            String clazzGrade = ExtraNameCodeUtil.extraObjName(dataObj, clazzGradeKey);
            String extraClazzName = ExtraNameCodeUtil.extraObjName(dataObj, nameKey);
            String extraClazzCode = ExtraNameCodeUtil.extraObjName(dataObj, codeKey);

            //准备提取院系处理
            String extraCollegeName = null;
            String extraCollegeCode = null;
            CollegeVO extraCollege = extraCollegeNameCode(collegeMap, dataObj, collegeNameKey, collegeCodeKey);
            String collegeErrorMessage = extraCollege.getErrorMessage();
            if (collegeErrorMessage == null) {
                //说明提取到了院系的数据
                extraCollegeName = extraCollege.getName();
                extraCollegeCode = extraCollege.getCode();
            } else {
                if (StrUtil.equals("1", collegeErrorMessage)) {
                    //没有填写院系名和院系代码
                    String errorName = extraClazzName == null ? extraClazzCode : extraClazzName;
                    errorList.add(StrUtil.format(ClazzError.NO_COLLEGE_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(collegeErrorMessage, excelName, "班级"));
                }
                continue;
            }

            //准备提取专业处理
            String extraMajorName = null;
            String extraMajorCode = null;
            MajorVO extraMajor = extraMajorNameCode(majorMap, dataObj, majorNameKey, majorCodeKey);
            String majorErrorMessage = extraMajor.getErrorMessage();
            if (majorErrorMessage == null) {
                //说明提取到了专业的数据
                extraMajorName = extraMajor.getName();
                extraMajorCode = extraMajor.getCode();
            } else {
                if (StrUtil.equals("1", majorErrorMessage)) {
                    //没有填写班级名和院系代码
                    String errorName = extraClazzName == null ? extraClazzCode : extraClazzName;
                    errorList.add(StrUtil.format(ClazzError.NO_MAJOR_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(majorErrorMessage, excelName, "班级"));
                }
                continue;
            }
            if (StrUtil.isBlank(extraClazzCode)) {
                //代码不存在,extraName肯定不是空,可能会存在生成代码的可能
                boolean existCode = false;
                //通过名字循环查找院系代码
                for (Object clazzObj : clazzMap.values()) {
                    ClazzVO clazz = (ClazzVO) clazzObj;
                    String name = clazz.getName();
                    if (StrUtil.equalsIgnoreCase(name, extraClazzName)) {
                        extraClazzCode = clazz.getCode();
                        existCode = true;
                        break;
                    }
                }
                if (!existCode) {
                    //使用名字也没找到院系代码
                    if (genClazz) {
                        int currentCount = recordCurrentMap.get(extraMajorCode) == null ? 1 : recordCurrentMap.get(extraMajorCode);
                        //班级代码的生成规则是院系+专业+年级+自增的数字
                        String parentCode = extraMajorCode + clazzGrade;
                        //设置了自动生成代码
                        GenCodeEntity genCodeEntity = ExtraNameCodeUtil.genCode4Data(parentCode, currentCount, clazzMap);
                        currentCount = genCodeEntity.getCurrentCount() + 1;
                        //记录当前学院自动生成代码的最大值
                        recordCurrentMap.put(extraMajorCode, currentCount);
                        extraClazzCode = genCodeEntity.getCode();
                        ClazzVO clazzVO = new ClazzVO();
                        clazzVO.setCode(extraClazzCode);
                        clazzVO.setName(extraClazzName);
                        clazzVO.setMajorCode(extraMajorCode);
                        clazzVO.setMajorName(extraMajorName);
                        clazzVO.setCollegeCode(extraMajor.getCollegeCode());
                        clazzVO.setCollegeName(extraMajor.getCollegeName());
                        clazzVO.setCampus(clazzCampus);
                        clazzVO.setClazzStudentNum(clazzNumber);
                        clazzVO.setGrade(clazzGrade);
                        //生成完后将组装好的班级数据存在临时缓存
                        clazzMap.put(extraClazzCode, clazzVO);
                    } else {
                        //未设置自动生成代码,直接报错处理
                        errorList.add(StrUtil.format(ClazzError.NO_CODE, excelName, extraClazzName));
                    }
                }
            } else {
                //代码不为空
                Object clazzObj = clazzMap.get(extraClazzCode);
                if (clazzObj == null) {
                    //指定的班级代码没有在临时缓存中
                    if (StrUtil.isBlank(extraClazzName)) {
                        errorList.add(StrUtil.format(ClazzError.NO_NAME, excelName, extraClazzCode));
                    } else {
                        ClazzVO clazzVO = new ClazzVO();
                        clazzVO.setCode(extraClazzCode);
                        clazzVO.setName(extraClazzName);
                        clazzVO.setMajorCode(extraMajorCode);
                        clazzVO.setMajorName(extraMajorName);
                        clazzVO.setCollegeCode(extraMajor.getCollegeCode());
                        clazzVO.setCollegeName(extraMajor.getCollegeName());
                        clazzVO.setCampus(clazzCampus);
                        clazzVO.setClazzStudentNum(clazzNumber);
                        clazzVO.setGrade(clazzGrade);
                        //生成完后将组装好的班级数据存在临时缓存
                        clazzMap.put(extraClazzCode, clazzVO);
                    }
                } else {
                    //通过代码在临时缓存找到教研室
                    ClazzVO clazzVO = (ClazzVO) clazzObj;
                    String clazzVOName = clazzVO.getName();
                    if (StrUtil.isNotBlank(extraClazzName)) {
                        //比对填写的院系名和缓存里面的院系名是否一样
                        if (!StrUtil.equalsIgnoreCase(extraClazzName, clazzVOName)) {
                            errorList.add(StrUtil.format(ClazzError.MULTI_NAME, excelName, extraClazzCode));
                        }
                    }
                    //相同班级,专业不一样
                    String cacheMajorCode = clazzVO.getMajorCode();
                    if (!StrUtil.equalsIgnoreCase(cacheMajorCode, extraMajorCode)) {
                        errorList.add(StrUtil.format(ClazzError.MULTI_MAJOR_CODE, excelName, extraClazzCode));
                    }
                }
            }

        }
        return clazzMap;
    }

    /**
     * 抽取学生数据
     *
     * @param collegeMap
     * @param majorMap
     * @param majorFxMap
     * @param clazzMap
     * @param dataList
     * @param studentKeyProperty
     * @param excelName
     * @return
     */
    public Map<String, Object> extractStudentData(Map<String, Object> collegeMap,
                                                  Map<String, Object> majorMap,
                                                  Map<String, Object> majorFxMap,
                                                  Map<String, Object> clazzMap,
                                                  List<Map<String, Object>> dataList,
                                                  StudentKeyProperty studentKeyProperty, String excelName) {
        Map<String, Object> studentMap = new HashMap<>();
        String nameKey = studentKeyProperty.getStudentNameKey();
        String codeKey = studentKeyProperty.getStudentCodeKey();
        //未设置key的话不能进行提取
        if (StrUtil.isBlank(nameKey) || StrUtil.isBlank(codeKey) || CollUtil.isEmpty(dataList)) {
            return studentMap;
        }
        String collegeNameKey = studentKeyProperty.getStudentCollegeNameKey();
        String collegeCodeKey = studentKeyProperty.getStudentCollegeCodeKey();
        String majorNameKey = studentKeyProperty.getStudentMajorNameKey();
        String majorCodeKey = studentKeyProperty.getStudentMajorCodeKey();
        String majorFxNameKey = studentKeyProperty.getStudentMajorFxNameKey();
        String majorFxCodeKey = studentKeyProperty.getStudentMajorFxCodeKey();
        String clazzNameKey = studentKeyProperty.getStudentClazzNameKey();
        String clazzCodeKey = studentKeyProperty.getStudentClazzCodeKey();
        String studentStatusKey = studentKeyProperty.getStudentStatus();
        String sexNameKey = studentKeyProperty.getStudentSexNameKey();
        String prePayKey = studentKeyProperty.getStudentPrePayKey();
        String gradeKey = studentKeyProperty.getStudentGradeKey();
        String yearKey = studentKeyProperty.getStudentYearKey();
        String campusKey = studentKeyProperty.getStudentCampusKey();
        for (Map<String, Object> dataObj : dataList) {
            //从excel的数据里抽取名字和代码
            String extraStudentName = ExtraNameCodeUtil.extraObjName(dataObj, nameKey);
            String extraStudentCode = ExtraNameCodeUtil.extraObjName(dataObj, codeKey);
            if (StrUtil.isBlank(extraStudentName) || StrUtil.isBlank(extraStudentCode)) {
                errorList.add(StrUtil.format(StudentError.NO_NAME_CODE, excelName));
                continue;
            }
            String sex = ExtraNameCodeUtil.extraObjName(dataObj, sexNameKey);
            String prePay = ExtraNameCodeUtil.extraObjName(dataObj, prePayKey);
            String grade = ExtraNameCodeUtil.extraObjName(dataObj, gradeKey);
            String status = ExtraNameCodeUtil.extraObjName(dataObj, studentStatusKey);
            if (StrUtil.isBlank(status)) {
                status = "在读";
            }
            String year = ExtraNameCodeUtil.extraObjName(dataObj, yearKey);
            String campus = ExtraNameCodeUtil.extraObjName(dataObj, campusKey);

            //准备提取院系处理
            String extraCollegeName = null;
            String extraCollegeCode = null;
            CollegeVO extraCollege = extraCollegeNameCode(collegeMap, dataObj, collegeNameKey, collegeCodeKey);
            String collegeErrorMessage = extraCollege.getErrorMessage();
            if (collegeErrorMessage == null) {
                //说明提取到了院系的数据
                extraCollegeName = extraCollege.getName();
                extraCollegeCode = extraCollege.getCode();
            } else {
                if (StrUtil.equals("1", collegeErrorMessage)) {
                    //没有填写院系名和院系代码
                    String errorName = extraStudentName == null ? extraStudentCode : extraStudentName;
                    errorList.add(StrUtil.format(StudentError.NO_COLLEGE_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(collegeErrorMessage, excelName, "学生"));
                }
                continue;
            }

            //准备提取专业处理
            String extraMajorName = null;
            String extraMajorCode = null;
            MajorVO extraMajor = extraMajorNameCode(majorMap, dataObj, majorNameKey, majorCodeKey);
            String majorErrorMessage = extraMajor.getErrorMessage();
            if (majorErrorMessage == null) {
                //说明提取到了专业的数据
                extraMajorName = extraMajor.getName();
                extraMajorCode = extraMajor.getCode();
            } else {
                if (StrUtil.equals("1", majorErrorMessage)) {
                    //没有填写班级名和院系代码
                    String errorName = extraStudentName == null ? extraStudentCode : extraStudentName;
                    errorList.add(StrUtil.format(StudentError.NO_MAJOR_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(majorErrorMessage, excelName, "学生"));
                }
                continue;
            }
            //准备提取专业处理
            String extraMajorFxName = null;
            String extraMajorFxCode = null;
            MajorFxVO extraMajorFx = extraMajorFxNameCode(majorFxMap, dataObj, majorFxNameKey, majorFxCodeKey);
            String majorFxErrorMessage = extraMajorFx.getErrorMessage();
            if (majorFxErrorMessage == null) {
                //专业方向名和专业方向代码只有有一个存在的,说明提取到了专业方向的数据
                if (StrUtil.isNotBlank(majorFxNameKey) || StrUtil.isNotBlank(majorFxCodeKey)) {
                    extraMajorFxName = extraMajorFx.getName();
                    extraMajorFxCode = extraMajorFx.getCode();
                }
            } else {
                if (StrUtil.equals("1", majorFxErrorMessage)) {
                    //没有填写班级名和院系代码
                    String errorName = extraStudentName == null ? extraStudentCode : extraStudentName;
                    errorList.add(StrUtil.format(StudentError.NO_MAJOR_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(majorFxErrorMessage, excelName, "学生"));
                }
                continue;
            }

            //准备提取班级处理
            String extraClazzName = null;
            String extraClazzCode = null;
            ClazzVO extraClazz = extraClazzNameCode(clazzMap, dataObj, clazzNameKey, clazzCodeKey);
            String clazzErrorMessage = extraClazz.getErrorMessage();
            if (clazzErrorMessage == null) {
                //说明提取到了专业的数据
                extraClazzName = extraClazz.getName();
                extraClazzCode = extraClazz.getCode();
            } else {
                if (StrUtil.equals("1", clazzErrorMessage)) {
                    //没有填写班级名和院系代码
                    String errorName = extraStudentName == null ? extraStudentCode : extraStudentName;
                    errorList.add(StrUtil.format(StudentError.NO_CLAZZ_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(clazzErrorMessage, excelName, "学生"));
                }
                continue;
            }

            Object extraStudentObj = studentMap.get(extraStudentCode);
            if (extraStudentObj == null) {
                //缓存里没有学生,添加进入缓存
                StudentVO studentVO = new StudentVO();
                studentVO.setName(extraStudentName);
                studentVO.setCode(extraStudentCode);
                studentVO.setClazzCode(extraClazzCode);
                studentVO.setClazzName(extraClazzName);
                studentVO.setMajorName(extraMajorName);
                studentVO.setMajorCode(extraMajorCode);
                studentVO.setCollegeName(extraCollegeName);
                studentVO.setCollegeCode(extraCollegeCode);
                studentVO.setMajorFxName(extraMajorFxName);
                studentVO.setMajorFxCode(extraMajorFxCode);
                //不需要关联的数据信息,直接复制就可以
                studentVO.setCampus(campus);
                studentVO.setGrade(grade);
                studentVO.setIntoYear(year);
                studentVO.setSex(sex);
                studentVO.setStatus(status);
                studentMap.put(extraStudentCode, studentVO);

            } else {
                //缓存有学生,取出来比对
                StudentVO studentVO = (StudentVO) extraStudentObj;
                String cacheStuName = studentVO.getName();
                String collegeCode = studentVO.getCollegeCode();
                String majorCode = studentVO.getMajorCode();
                String clazzCode = studentVO.getClazzCode();
                String majorFxCode = studentVO.getMajorFxCode();
                String errorStr = "{}表存在{}的学号[{}]存在不同{}错误";
                if (!StrUtil.equalsIgnoreCase(clazzCode, extraClazzCode)) {
                    //班级代码不一样
                    errorList.add(StrUtil.format(errorStr, excelName, "学生", extraStudentCode, "院系"));
                    continue;
                }
                if (!StrUtil.equalsIgnoreCase(majorFxCode, extraMajorFxCode)) {
                    //专业方向代码不一样
                    errorList.add(StrUtil.format(errorStr, excelName, "学生", extraStudentCode, "专业方向"));
                    continue;
                }
                if (!StrUtil.equalsIgnoreCase(majorCode, extraMajorCode)) {
                    //专业代码不一样
                    errorList.add(StrUtil.format(errorStr, excelName, "学生", extraStudentCode, "院系"));
                    continue;
                }
                if (!StrUtil.equalsIgnoreCase(collegeCode, extraCollegeCode)) {
                    //院系代码不一样
                    errorList.add(StrUtil.format(errorStr, excelName, "学生", extraStudentCode, "院系"));
                    continue;
                }
                if (!StrUtil.equalsIgnoreCase(cacheStuName, extraStudentName)) {
                    //名字不一样
                    errorList.add(StrUtil.format("{}表存在学生的学号{}从在多个名字的错误.", excelName, extraStudentCode));
                    continue;
                }
            }
            //提取学生数据
        }
        return studentMap;
    }

    /**
     * 抽取院系
     *
     * @param collegeMap
     * @param dataMap
     * @param nameKey
     * @param codeKey
     * @return
     */
    public CollegeVO extraCollegeNameCode(Map<String, Object> collegeMap, Map<String, Object> dataMap, String nameKey, String codeKey) {
        CollegeVO collegeVO = new CollegeVO();
        String cellCode = null;
        if (StrUtil.isNotBlank(codeKey)) {
            //用院系的code关联
            Object codeValue = dataMap.get(codeKey);
            if (codeValue != null) {
                //获取excel填写的院系代码
                cellCode = codeValue.toString().trim();
                if (StrUtil.isNotBlank(cellCode)) {
                    //从已经缓存好的院系里面取数据
                    Object collegeObj = collegeMap.get(cellCode);
                    if (collegeObj != null) {
                        CollegeVO collegeVOTmp = (CollegeVO) collegeObj;
                        collegeVOTmp.setErrorMessage(null);
                        return collegeVOTmp;
                    }
                    collegeVO.setErrorMessage("{}表里存在{}找不到对应的院系,院系代码[" + cellCode + "].");
                }
            }
        }
        if (StrUtil.isNotBlank(nameKey)) {
            //用name关联
            Object nameValue = dataMap.get(nameKey);

            if (nameValue != null) {
                //从已经缓存好的院系里面取数据
                String cellName = nameValue.toString().trim();
                if (StrUtil.isNotBlank(cellName)) {
                    for (Object obj : collegeMap.values()) {
                        CollegeVO collegeVOTmp = (CollegeVO) obj;
                        String name = collegeVOTmp.getName();

                        if (StrUtil.equalsIgnoreCase(name, cellName)) {
                            String code = collegeVOTmp.getCode();
                            if (StrUtil.isNotBlank(cellCode)) {
                                if (!StrUtil.equalsIgnoreCase(code, cellCode)) {
                                    collegeVO.setErrorMessage("{}表里的院系名[" + cellName + "]存在多个代码的错误.");
                                    return collegeVO;
                                }
                            } else {
                                collegeVOTmp.setErrorMessage(null);
                                return collegeVOTmp;
                            }
                        }
                    }
                    //通过名字没有找到
                    //取不到所属的院系,说明此条数据是错误数据
                    collegeVO.setErrorMessage("{}表里存在{}找不到对应的院系,院系名[" + cellName + "].");
                }
            }
        }
        String errorMessage = collegeVO.getErrorMessage();
        if (StrUtil.isBlank(errorMessage)) {
            collegeVO.setErrorMessage("1");
        }
        return collegeVO;
    }

    /**
     * 抽取专业
     *
     * @param majorMap
     * @param dataMap
     * @param nameKey
     * @param codeKey
     * @return
     */
    private MajorVO extraMajorNameCode(Map<String, Object> majorMap, Map<String, Object> dataMap, String nameKey, String codeKey) {
        MajorVO majorVO = new MajorVO();
        if (StrUtil.isNotBlank(codeKey)) {
            //用code关联
            Object codeValue = dataMap.get(codeKey);
            if (codeValue != null) {
                //从已经缓存好的院系里面取数据
                Object majorObj = majorMap.get(codeValue.toString());
                if (majorObj != null) {
                    return (MajorVO) majorObj;
                }
                majorVO.setErrorMessage("{}表里存在{}找不到对应的专业,专业代码[" + codeValue.toString() + "].");
            }
        }
        if (StrUtil.isNotBlank(nameKey)) {
            //用name关联
            Object nameValue = dataMap.get(nameKey);
            String majorCode = null;
            if (nameValue != null) {
                //从已经缓存好的院系里面取数据
                String majorName = nameValue.toString().trim();
                for (Object obj : majorMap.values()) {
                    MajorVO majorVOTmp = (MajorVO) obj;
                    String name = majorVOTmp.getName();
                    if (StrUtil.equalsIgnoreCase(name, majorName)) {
                        majorVOTmp.setErrorMessage(null);
                        return majorVOTmp;
                    }
                }
                if (StrUtil.isBlank(majorCode)) {
                    //取不到所属的专业,说明此条数据是错误数据
                    majorVO.setErrorMessage("{}表里存在{}找不到对应的专业,专业名[" + majorName + "].");
                    return majorVO;
                }
            }
        }
        String errorMessage = majorVO.getErrorMessage();
        if (StrUtil.isNotBlank(errorMessage)) {
            majorVO.setErrorMessage("1");
        }
        return majorVO;
    }

    /**
     * 抽取班级
     *
     * @param clazzMap
     * @param dataMap
     * @param nameKey
     * @param codeKey
     * @return
     */
    private ClazzVO extraClazzNameCode(Map<String, Object> clazzMap, Map<String, Object> dataMap, String nameKey, String codeKey) {
        ClazzVO clazzVO = new ClazzVO();
        if (StrUtil.isNotBlank(codeKey)) {
            //用code关联
            Object codeValue = dataMap.get(codeKey);
            if (codeValue != null) {
                //从已经缓存好的院系里面取数据
                Object clazzObj = clazzMap.get(codeValue.toString());
                if (clazzObj != null) {
                    return (ClazzVO) clazzObj;
                }
                clazzVO.setErrorMessage("{}表里存在{}找不到对应的班级,班级代码[" + codeValue.toString() + "].");
            }
        }
        if (StrUtil.isNotBlank(nameKey)) {
            //用name关联
            Object nameValue = dataMap.get(nameKey);
            String clazzCode = null;
            if (nameValue != null) {
                //从已经缓存好的院系里面取数据
                String clazzName = nameValue.toString().trim();
                for (Object obj : clazzMap.values()) {
                    ClazzVO clazzVOTmp = (ClazzVO) obj;
                    String name = clazzVOTmp.getName();
                    if (StrUtil.equalsIgnoreCase(name, clazzName)) {
                        clazzVOTmp.setErrorMessage(null);
                        return clazzVOTmp;
                    }
                }
                //取不到所属的班级,说明此条数据是错误数据
                clazzVO.setErrorMessage("{}表里存在{}找不到对应的班级,班级名[" + clazzName + "].");
                return clazzVO;
            }
        }
        String errorMessage = clazzVO.getErrorMessage();
        if (StrUtil.isNotBlank(errorMessage)) {
            clazzVO.setErrorMessage("1");
        }
        return clazzVO;
    }

    /**
     * 抽取专业方向
     *
     * @param majorFxMap
     * @param dataMap
     * @param nameKey
     * @param codeKey
     * @return
     */
    private MajorFxVO extraMajorFxNameCode(Map<String, Object> majorFxMap, Map<String, Object> dataMap,
                                           String nameKey, String codeKey) {
        MajorFxVO majorFxVO = new MajorFxVO();
        if (StrUtil.isBlank(nameKey) && StrUtil.isBlank(codeKey)) {
            majorFxVO.setErrorMessage(null);
            return majorFxVO;
        }
        if (StrUtil.isNotBlank(codeKey)) {
            //用code关联
            Object codeValue = dataMap.get(codeKey);
            if (codeValue != null) {
                String codeStr = codeValue.toString().trim();
                if (StrUtil.isBlank(codeStr)) {
                    majorFxVO.setErrorMessage(null);
                    return majorFxVO;
                }
                //从已经缓存好的院系里面取数据
                Object majorObj = majorFxMap.get(codeStr);
                if (majorObj != null) {
                    return (MajorFxVO) majorObj;
                }
                majorFxVO.setErrorMessage("专业方向代码[" + codeValue.toString() + "].");
            }
        }
        if (StrUtil.isNotBlank(nameKey)) {
            //用name关联
            Object nameValue = dataMap.get(nameKey);
            String majorFxCode = null;
            if (nameValue != null) {
                //从已经缓存好的院系里面取数据
                String majorFxName = nameValue.toString().trim();
                if (StrUtil.isBlank(majorFxName)) {
                    majorFxVO.setErrorMessage(null);
                    return majorFxVO;
                }
                for (Object obj : majorFxMap.values()) {
                    MajorFxVO majorFxVOTmp = (MajorFxVO) obj;
                    String name = majorFxVOTmp.getName();
                    if (StrUtil.equalsIgnoreCase(name, majorFxName)) {
                        majorFxVOTmp.setErrorMessage(null);
                        return majorFxVOTmp;
                    }
                }
                if (StrUtil.isBlank(majorFxCode)) {
                    //取不到所属的专业,说明此条数据是错误数据
                    majorFxVO.setErrorMessage("专业方向名[" + majorFxName + "].");
                    return majorFxVO;
                }
            }
        }
        return majorFxVO;
    }

}
